﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using KC.Framework.Tenant;
using KC.DTO.Account;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization;
using KC.Framework.Exceptions;
using KC.Framework.Base;

namespace KC.Web.Account.Controllers
{
    [MVC.Core.Extension.MenuFilter("组织管理", "组织架构管理", "/Organization/Index",
        Version = TenantConstant.DefaultVersion, TenantType = TenantConstant.DefaultTenantType, SmallIcon = "fa fa-sitemap", AuthorityId = "4DB22A38-1759-40B2-9926-44FACFA59E68",
        DefaultRoleId = RoleConstants.AdminRoleId, Order = 1, IsExtPage = false, Level = 3)]
    public class OrganizationController : AccountBaseController
    {
        public OrganizationController(
            Tenant tenant,
            IServiceProvider serviceProvider,
            ILogger<OrganizationController> logger)
            : base(tenant, serviceProvider, logger)
        {
        }

        [MVC.Core.Extension.PermissionFilter("组织架构管理", "组织架构管理", "/Organization/Index", "4DB22A38-1759-40B2-9926-44FACFA59E68",
            DefaultRoleId = RoleConstants.AdminRoleId, Order = 1, IsPage = true, ResultType = ResultType.ActionResult)]
        public IActionResult Index()
        {
            ViewBag.BusinessTypes = base.GetDropDownItemsByEnum<BusinessType>();
            return View();
        }

        //[MVC.Core.Extension.PermissionFilter("组织架构管理", "加载组织架构列表数据", "/Organization/LoadOrganizationList",
        //    DefaultRoleId = RoleConstants.AdminRoleId, Order = 1, IsPage = false, ResultType = ResultType.JsonResult)]
        public IActionResult LoadOrganizationList(string searchKey = "", string searchValue = "")
        {
            string name = string.Empty;
            if (!string.IsNullOrWhiteSpace(searchKey)
                && !string.IsNullOrWhiteSpace(searchValue))
            {
                switch (searchKey.ToLower())
                {
                    case "name":
                        name = searchValue;
                        break;
                }
            }

            var result = SysManageService.GetOrganizationsTreesByName(name);

            return Json(result);
        }

        [AllowAnonymous]
        public IActionResult LoadOrganizationTree()
        {
            var tree = SysManageService.GetAllOrganizationTrees();
            var rootMenu = new OrganizationDTO() { text = "顶级菜单", children = tree };
            return Json(new List<OrganizationDTO> { rootMenu });
        }
        [AllowAnonymous]
        public IActionResult LoadOrganizationOneLevelTree(int id)
        {
            var tree = SysManageService.GetAllOrganizationTrees();
            var orgs = SysManageService.GetOrganizationTreesByIds(new List<int> { id });

            var rootMenu = new OrganizationDTO() { text = "顶级菜单", children = tree };
            var org = RemoveOrganizationsByIds(rootMenu, orgs.Select(o => o.id).ToList());
            return Json(new List<OrganizationDTO> { rootMenu });
        }
        [AllowAnonymous]
        public PartialViewResult GetOrganizationForm(int id = 0, int parentId = 0)
        {
            ViewBag.BusinessTypes = base.GetDropDownItemsByEnum<BusinessType>();
            var model = SysManageService.GetOrganizationById(id) ?? new OrganizationDTO();
            ViewBag.appid = CurrentOperationApplicationId;
            return PartialView("_organizationForm", model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        [MVC.Core.Extension.PermissionFilter("组织架构管理", "保存组织架构", "/Organization/SaveOrganizationForm", "0EBCF1F7-3E2A-4A0E-AF90-36689ABB0AA3",
            DefaultRoleId = RoleConstants.AdminRoleId, Order = 2, IsPage = false, ResultType = ResultType.JsonResult)]
        public JsonResult SaveOrganizationForm(OrganizationDTO model)
        {
            if (model.ParentId == 0)
                model.ParentId = null;
            ModelState.Remove("OrganizationID");
            ModelState.Remove("Status");
            ModelState.Remove("Leaf");
            ModelState.Remove("IsDeleted");
            ModelState.Remove("CreatedDate");
            ModelState.Remove("ModifiedDate");
            //if (!ModelState.IsValid)
            //     return base.ThrowErrorJsonMessage(false, "数据有误，请详查!");
            //if (model.ParentId)
            //{
            //}
            //var parentOrganization1 = SysManageService.GetOrganizationById(model.ParentId.Value);
            //return base.ThrowErrorJsonMessage(false, model.ParentName);
            return GetServiceJsonResult(() =>
            {
                model.Level = 1;
                if (model.ParentId.HasValue && model.ParentId > 0)
                {
                    var parentOrganization = SysManageService.GetOrganizationById(model.ParentId.Value);
                    if (null == parentOrganization)
                    {
                        throw new ArgumentException(string.Format("父级ID:{0} 未找到！", model.ParentId));
                    }
                    if (parentOrganization.Level >= 4)
                    {
                        throw new ArgumentException(string.Format("父级:{0} 不能作为父级！", model.Name));
                    }

                    model.Level = parentOrganization.Level + 1;
                }
                if (model.id > 0)
                {


                    List<OrganizationDTO> organizationchild = SysManageService.GetOrganizationTreesByIds(new List<int> { model.id });
                    foreach (var item in organizationchild)
                    {
                        if (item.Level.Equals(4))
                        {
                            throw new ArgumentException("此节点为父节点且有等级为4的子级，不可移动到其他父节点下");
                        }

                    }

                }
                model.CreatedDate = DateTime.UtcNow;
                model.ModifiedDate = DateTime.UtcNow;
                return SysManageService.SaveOrganization(model);
            });

        }

        [MVC.Core.Extension.PermissionFilter("组织架构管理", "删除组织架构", "/Organization/RemoveOrganization", "93F6DC06-6426-41DF-9DB8-C0FA0758FBB7",
            DefaultRoleId = RoleConstants.AdminRoleId, Order = 3, IsPage = false, ResultType = ResultType.JsonResult)]
        public JsonResult RemoveOrganization(int id)
        {
            return GetServiceJsonResult(() =>
            {
                var organization = SysManageService.GetOrganizationById(id);
                if (null == organization)
                {
                    throw new ArgumentException(string.Format("未找到菜单ID:{0}", id));
                }
                if (organization.children.Any())
                {
                    throw new ArgumentException(string.Format("菜单ID:{0}存在子菜单，无法删除，请先删除子菜单！", id));
                }
                var organization2 = SysManageService.GetOrganizationsWithUsersByOrgId(id);
                if (organization2.Users.Count > 0)
                {
                    throw new BusinessPromptException(string.Format("存在下属员工，无法删除，请先移除下属员工！"));
                }
                return SysManageService.RemoveOrganization(id);
            });
        }

        [AllowAnonymous]
        public JsonResult ExistOrganizationName(string name, int id = 0)
        {
            var tname = SysManageService.ExistOrganizationName(id, name);
            return Json(tname);
        }

        private OrganizationDTO RemoveOrganizationsByIds(OrganizationDTO tree, List<int> ids)
        {
            if (tree.children.Any(o => ids.Contains(o.id)))
                tree.children.RemoveAll(o => ids.Contains(o.id));
            if (tree.Level == 3)
                tree.children = null;
            if (tree.children != null)
            {
                foreach (var child in tree.children)
                {
                    RemoveOrganizationsByIds(child, ids);
                }
            }
            return tree;
        }
        private OrganizationDTO GetOrganizationTreeOneLevel(OrganizationDTO tree)
        {
            if (tree.Level == 3)
                tree.children = null;
            if (null != tree.children)
            {
                foreach (var child in tree.children)
                {
                    GetOrganizationTreeOneLevel(child);
                }
            }
            return tree;
        }
    }
}